import pandas as pd
from sklearn.preprocessing import label_binarize
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import LeaveOneOut
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score

raw_data = pd.read_excel('./test1-dataset/数据集.xls')
raw_data['feature2'] = pd.to_numeric(raw_data['feature2'], errors='coerce')
raw_data.dropna(inplace=True, how='any')

x0 = raw_data.iloc[:, 1:]
y0 = raw_data['label']

loo = LeaveOneOut()

model = RandomForestClassifier(n_estimators=100)

accuracy = []
precision = []
recall = []
f1 = []
auc = []

for train, test in loo.split(x0, y0):
    model: RandomForestClassifier = model.fit(x0.iloc[train], y0.iloc[train])
    y_test_hot = label_binarize(y0.iloc[test], classes=[0, 1, 2, 3, 4, 5])
    y_score = model.predict_proba(x0.iloc[test]) # 预测概率
    try:
        auc.append(roc_auc_score(y_test_hot, y_score, average='micro'))
    except ValueError as e:
        print(e)
    
    accuracy.append(accuracy_score(y0.iloc[test], model.predict(x0.iloc[test])))
    precision.append(precision_score(y0.iloc[test], model.predict(x0.iloc[test]), zero_division=1, average='macro'))
    recall.append(recall_score(y0.iloc[test], model.predict(x0.iloc[test]), zero_division=1, average='macro'))
    f1.append(f1_score(y0.iloc[test], model.predict(x0.iloc[test]), zero_division=1, average='macro'))

print(f'''
    accuracy: {sum(accuracy)/len(accuracy)},
    precision: {sum(precision)/len(precision)},
    recall: {sum(recall)/len(recall)},
    f1: {sum(f1)/len(f1)},
    auc: {sum(auc)/len(auc)},
''')
